home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 008a / xmsif140.zip / XMSTEST.C < prev    next >
C/C++ Source or Header  |  1991-12-08  |  52KB  |  1,145 lines

  1. /***************************************************************************
  2. *   xmstest.c                                                              *
  3. *   MODULE:  XMSIF                                                         *
  4. *   OS:      DOS                                                           *
  5. *   VERSION: 1.1                                                           *
  6. *   DATE:    12/08/91                                                      *
  7. *                                                                          *
  8. *   Copyright (c) 1991 James W. Birdsall. All Rights Reserved.             *
  9. *                                                                          *
  10. *   Requires xmsif.h, testutil.h, and xmstest.h to compile.                *
  11. *   Compiles under Borland C++ 2.0, Turbo C 2.0, or MSC 6.00A.             *
  12. *                                                                          *
  13. *   Regression test and example for XMSIF.                                 *
  14. *                                                                          *
  15. *   This file is part one of the regression tester and example for XMSIF.  *
  16. *   The other parts are named EMSTEST2.C and EMSTEST3.C. All three parts   *
  17. *   must be compiled and linked together along with the appropriate XMSIF  *
  18. *   library to produce the tester executable. This program compiles under  *
  19. *   tiny, small, medium, compact, large, and huge models.                  *
  20. *                                                                          *
  21. *   To use this tester: in general, just run it. Depending on what XMS     *
  22. *   driver you have, you may need to use the "-q" option. HIMEM.SYS does   *
  23. *   not require this option; QEMM 5.1* does; I don't know about other XMS  *
  24. *   drivers. If you haven't used it and should, or should use it and       *
  25. *   haven't, the tester can detect this and will abort with a message      *
  26. *   suggesting you do the opposite of whatever you did. For more detail on *
  27. *   what this option actually does, see below. The tester produces output  *
  28. *   on stdout. It performs 70+ tests, depending on the exact configuration *
  29. *   of your system, and parts of it run quite fast. If you want to read    *
  30. *   all the output, you should redirect the output to a file (but first    *
  31. *   you should probably run it straight to get an idea of how long it      *
  32. *   takes on your machine). If you just want to see whether the tests all  *
  33. *   pass, just run it -- if a test fails, execution aborts immediately.    *
  34. *                                                                          *
  35. *   Certain types of failure may cause XMSTEST to not deallocate memory    *
  36. *   that it has allocated. This should only occur if the library itself is *
  37. *   malfunctioning (which should never happen to you, only to me!) or if   *
  38. *   you are trying a different compiler or unsupported memory model and    *
  39. *   the compiler and library are therefore not communicating properly. It  *
  40. *   may also happen if you press control-break.                            *
  41. *                                                                          *
  42. *                                                                          *
  43. *   The actions XMSTEST takes may be broken down into two parts: EMB tests *
  44. *   and UMB tests. In the first part, it tests the XMM* functions which    *
  45. *   operate on extended memory blocks (EMBs). In the second part, it tests *
  46. *   the UMB* functions which operate on upper memory blocks (UMBs). Before *
  47. *   doing any of this, it tries to initialize XMSIF, which checks for the  *
  48. *   presence of an XMS driver, and aborts if there isn't one. Then it      *
  49. *   starts the first part, performing various preliminary tests on EMBs.   *
  50. *   If it determines that there isn't a large enough EMB free, it reports  *
  51. *   this and skips the copying function tests (tests of _XMMcopy() and     *
  52. *   _XMMicopy()), otherwise it performs the copying function tests. Then   *
  53. *   it starts the second part by trying to determine whether your system   *
  54. *   has UMBs. If it does not, it reports this fact and skips the rest of   *
  55. *   the UMB tests. If it does, it performs the rest of the UMB tests. If   *
  56. *   you see a message about "another broken system", that means that your  *
  57. *   XMS driver's support of UMBs is somewhat flaky, and the workarounds    *
  58. *   already built into XMSIF were unable to cover the problem. In this     *
  59. *   case, it will perform the rest of the UMB tests but is unable to check *
  60. *   that the functions actually did anything -- i.e. it can check the      *
  61. *   return code from the function, but cannot independently verify via     *
  62. *   other functions that the desired effect was actually achieved. See the *
  63. *   XMSIF documentation for a description of problems seen in the UMB      *
  64. *   support of various XMS drivers.                                        *
  65. *                                                                          *
  66. *   The "-q" option covers for some unusual behavior observed in QEMM      *
  67. *   5.1* which may also occur in other XMS drivers which provide EMS       *
  68. *   services as well. In QEMM's case, when extended memory is allocated,   *
  69. *   the total amount of XMS still available is decreased by the allocation *
  70. *   size rounded up to the nearest _16K_ (the EMS page size) instead of to *
  71. *   the nearest 1K (the XMS minimum allocation unit). HIMEM.SYS does not   *
  72. *   display this behavior. The "-q" option tells XMSTEST to expect a drop  *
  73. *   of a multiple of 16K after an allocation instead of a multiple of 1K.  *
  74. *   While XMSTEST can easily detect the difference, this option was added  *
  75. *   so that XMSTEST would which multiple was expected and could detect     *
  76. *   incorrect drops more reliably.                                         *
  77. *                                                                          *
  78. *                                                                          *
  79. *   Turbo C and older versions of Turbo C++ do not have the _fmemcmp() and *
  80. *   _fmemset() functions; I don't know about older versions of MSC. If     *
  81. *   your compiler does not have these functions, define the symbol         *
  82. *   NO_FFUNC and functions in this file will be used instead.              *
  83. *                                                                          *
  84. ***************************************************************************/
  85.  
  86. /*
  87. ** system includes <>
  88. */
  89.  
  90. #include <stdio.h>
  91. #include <stdlib.h>
  92. #include <dos.h>
  93. #include <string.h>
  94. #include <ctype.h>
  95.  
  96.  
  97. /*
  98. ** custom includes ""
  99. */
  100.  
  101. #include "xmsif.h"
  102. #include "xmstest.h"
  103.  
  104. #include "testutil.h"
  105.  
  106. /*
  107. ** local #defines
  108. */
  109.  
  110. /*
  111. ** misc: copyright strings, version macros, etc.
  112. */
  113.  
  114. /*
  115. ** typedefs
  116. */
  117.  
  118. /*
  119. ** global variables
  120. */
  121.  
  122. int testno = 1;                     /* number of test currently being done  */
  123. char *gblmsg = "";                  /* msg to be printed in test header     */
  124.  
  125. int qflag = 0;                      /* running QEMM or not?                 */
  126.  
  127.  
  128. /*
  129. ** static globals
  130. */
  131.  
  132. /*
  133. ** function prototypes
  134. */
  135.  
  136. /*
  137. ** functions
  138. */
  139.  
  140.  
  141. /***************************************************************************
  142. *   FUNCTION: MAIN                                                         *
  143. *                                                                          *
  144. *   DESCRIPTION:                                                           *
  145. *                                                                          *
  146. *       The master function.                                               *
  147. *                                                                          *
  148. *   ENTRY:                                                                 *
  149. *                                                                          *
  150. *       None.                                                              *
  151. *                                                                          *
  152. *   EXIT:                                                                  *
  153. *                                                                          *
  154. *       Void.                                                              *
  155. *                                                                          *
  156. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  157. *                                                                          *
  158. ***************************************************************************/
  159. main(int argc, char *argv[])
  160. {
  161.     int status;                     /* return status from library functions */
  162.     unsigned int version;
  163.  
  164.     if (argc > 1)
  165.     {
  166.         if ((argv[1][0] == '-') || (argv[1][0] == '/'))
  167.         {
  168.             if (toupper(argv[1][1]) == 'Q')
  169.             {
  170.                 qflag = 1;
  171.             }
  172.             else
  173.             {
  174.                 printf("Usage: XMSTEST [-q]\n");
  175.                 exit(1);
  176.             }
  177.         }
  178.         else
  179.         {
  180.             printf("Usage: XMSTEST [-q]\n");
  181.             exit(1);
  182.         }
  183.     }
  184.  
  185.     /* set banner */
  186.     gblmsg = "  PRELIMINARY EMB TESTS";
  187.  
  188.     /*
  189.     ** check initialization test
  190.     */
  191.     TESTHEADER();
  192.     printf("Making a call to XMMgetversion() before calling XMMlibinit().\n");
  193.     printf("The call should fail.\n");
  194.     XMMgetversion();
  195.     nofailcheck("XMMgetversion()", (int) _XMMerror, (void far *) NULL, 0, 0);
  196.     weirdcodechk("XMMgetversion()", XMM_NOINIT, (void far *) NULL, 0, 0);
  197.     TESTTAILER();
  198.  
  199.  
  200.     /*
  201.     ** initialize XMSIF
  202.     */
  203.     TESTHEADER();
  204.     printf("Calling XMMlibinit().\n");
  205.     printf("Should succeed if Extended Memory Manager is present.\n");
  206.     status = XMMlibinit();
  207.     switch (status)
  208.     {
  209.         case XMMOOPS:
  210.             printf("XMMlibinit() failed, code 0x%X.\n",
  211.                                                     (unsigned int) _XMMerror);
  212.             exit(3);
  213.             break;
  214.  
  215.         case NOXMM:
  216.             printf("XMMlibinit() did not find an Extended Memory Manager.\n");
  217.             exit(3);
  218.             break;
  219.  
  220.         case 0:
  221.             printf("XMMlibinit() returned OK.\n");
  222.             weirdcodechk("XMMlibinit()", 0, (void far *) NULL, 0, 0);
  223.             break;
  224.  
  225.         default:
  226.             printf("XMMlibinit() returned strange value %d.\n", status);
  227.             exit(3);
  228.             break;
  229.     }
  230.     TESTTAILER();
  231.  
  232.  
  233.     /*
  234.     ** test version call
  235.     */
  236.     TESTHEADER();
  237.     printf("Testing XMMgetversion().\n");
  238.     printf("Results should match value in _XMMversion.\n");
  239.     version = XMMgetversion();
  240.     weirdcodechk("XMMgetversion()", 0, (void far *) NULL, 0, 0);
  241.     if (version != (int) _XMMversion)
  242.     {
  243.         printf("XMMgetversion() [0x%X] and _XMMversion [0x%X] differ.\n",
  244.                                           version, (unsigned int) _XMMversion);
  245.         exit(3);
  246.     }
  247.     printf("XMS version %d.%02d.\n", ((version >> 8) & 0xFF), (version & 0xFF));
  248.     TESTTAILER();
  249.  
  250.  
  251.     /*
  252.     ** test allocation functions
  253.     */
  254.     if (do_alloc_tests(1L) == 0)
  255.     {
  256.         do_alloc_tests(16384L);
  257.         do_alloc_tests(85555L);
  258.         do_alloc_tests(0L);
  259.  
  260.         /*
  261.         ** test rawcall interface
  262.         */
  263.         do_rawcall_tests();
  264.  
  265.         /*
  266.         ** test copies
  267.         */
  268.         do_copy_tests();
  269.     }
  270.  
  271.     /*
  272.     ** test UMB functions (if possible)
  273.     */
  274.     do_UMB_tests();
  275.  
  276.     /* end and cleanup */
  277.     printf(">>>END\n");
  278.     printf("All tests succeeded.\n");
  279.  
  280.     exit(0);
  281. } /* end of main() */
  282.  
  283.  
  284. /***************************************************************************
  285. *   FUNCTION: DO_ALLOC_TESTS                                               *
  286. *                                                                          *
  287. *   DESCRIPTION:                                                           *
  288. *                                                                          *
  289. *       This function tests XMSIF calls XMMcoreleft(), XMMallcoreleft(),   *
  290. *       XMMalloc(), and XMMfree().                                         *                *
  291. *                                                                          *
  292. *   ENTRY:                                                                 *
  293. *                                                                          *
  294. *       bytes - number of bytes of XMS to try to allocate.                 *
  295. *                                                                          *
  296. *   EXIT:                                                                  *
  297. *                                                                          *
  298. *       Void.                                                              *
  299. *                                                                          *
  300. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  301. *                                                                          *
  302. ***************************************************************************/
  303. int do_alloc_tests(unsigned long bytes)
  304. {
  305.     unsigned long xmsfree, xmsfree2;
  306.     unsigned long xmsallfree, xmsallfree2;
  307.     unsigned long rndlen, pagelen;
  308.     int handle;
  309.  
  310.     /* get bytes value rounded up to nearest K */
  311.     rndlen = bytes + 1023L;
  312.     rndlen &= 0xFFFFFC00L;
  313.     /* get bytes value rounded up to nearest 16K */
  314.     pagelen = bytes + 16383L;
  315.     pagelen &= 0xFFFFC000L;
  316.  
  317.     /* test coreleft */
  318.     TESTHEADER();
  319.     printf("Testing XMMcoreleft().\n");
  320.     printf("Result should be multiple of 1024.\n");
  321.     xmsfree = test_XMMcoreleft();
  322.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  323.                                                   xmsfree, (xmsfree / 1024L));
  324.     TESTTAILER();
  325.  
  326.     /* test allcoreleft */
  327.     TESTHEADER();
  328.     printf("Testing XMMallcoreleft().\n");
  329.     printf("Result should be multiple of 1024 and >= XMMcoreleft().\n");
  330.     xmsallfree = test_XMMallcoreleft();
  331.     if (xmsallfree >= xmsfree)
  332.     {
  333.         printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  334.                                              xmsallfree, (xmsallfree / 1024L));
  335.     }
  336.     else
  337.     {
  338.         printf("XMMallcoreleft() returned low value %lu.\n", xmsallfree);
  339.         exit(3);
  340.     }
  341.  
  342.     /* make sure enough free */
  343.     if (xmsallfree < MINFREE)
  344.     {
  345.         printf("Insufficient free XMS to perform all tests. Aborting EMB tests.\n");
  346.         return 1;
  347.     }
  348.     /* enough free, but is it unfragmented enough to be useable? */
  349.     if (xmsfree < MINFREE)
  350.     {
  351.         /* largest block isn't big enough -- can't finish tests */
  352.         printf("XMS too fragmented to perform all tests. Aborting EMB tests.\n");
  353.         return 1;
  354.     }
  355.  
  356.     /* test allocation */
  357.     TESTHEADER();
  358.     printf("Testing XMMalloc(%lu).\n", bytes);
  359.     printf("Should succeed. Free XMS should drop by %lu bytes (%luK).\n",
  360.                                                      rndlen, (rndlen / 1024L));
  361.     handle = test_XMMalloc(bytes);
  362.     printf("XMMalloc() returned OK.\n");
  363.     xmsfree2 = test_XMMcoreleft();
  364.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  365.                                                  xmsfree2, (xmsfree2 / 1024L));
  366.     xmsallfree2 = test_XMMallcoreleft();
  367.     printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  368.                                            xmsallfree2, (xmsallfree2 / 1024L));
  369.     if ((xmsallfree - xmsallfree2) != ((qflag == 0) ? rndlen : pagelen))
  370.     {
  371.         printf("XMMalloc(%lu) caused total free to drop from %lu to %lu.\n",
  372.                                                bytes, xmsallfree, xmsallfree2);
  373.         if (((xmsallfree - xmsallfree2) % ((qflag == 0) ? 16384L:1024L)) == 0L)
  374.         {
  375.             printf("Try %s the -q switch.\n",
  376.                                        ((qflag == 0) ? "using" : "not using"));
  377.         }
  378.         XMMfree(handle);
  379.         exit(3);
  380.     }
  381.     TESTTAILER();
  382.  
  383.     /* test free */
  384.     TESTHEADER();
  385.     printf("Testing XMMfree() on handle just returned by XMMalloc().\n");
  386.     printf("Should succeed. Free XMS should increase by %lu bytes (%luK).\n",
  387.                                                      rndlen, (rndlen / 1024L));
  388.     test_XMMfree(handle);
  389.     printf("XMMfree() returned OK.\n");
  390.     xmsfree2 = test_XMMcoreleft();
  391.     printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  392.                                                  xmsfree2, (xmsfree2 / 1024L));
  393.     xmsallfree2 = test_XMMallcoreleft();
  394.     printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
  395.                                            xmsallfree2, (xmsallfree2 / 1024L));
  396.     if (xmsallfree2 != xmsallfree)
  397.     {
  398.         printf("Freeing handle returned by XMMalloc() did not restore\n");
  399.         printf("   total free XMS count -- was %lu originally, now %lu.\n",
  400.                                                       xmsallfree, xmsallfree2);
  401.         exit(3);
  402.     }
  403.     TESTTAILER();
  404.  
  405.     /* make sure enough free */
  406.     if (xmsallfree < MINFREE)
  407.     {
  408.         printf("Insufficient free XMS to perform all tests. Aborting.\n");
  409.         exit(1);
  410.     }
  411.     /* enough free, but is it unfragmented enough to be useable? */
  412.     if (xmsfree < MINFREE)
  413.     {
  414.         /* largest block isn't big enough -- can't finish tests */
  415.         printf("XMS too fragmented to perform all tests. Aborting.\n");
  416.         exit(1);
  417.     }
  418.  
  419.     return 0;
  420. } /* end of do_alloc_tests() */
  421.  
  422.  
  423. /***************************************************************************
  424. *   FUNCTION: DO_RAWCALL_TESTS                                             *
  425. *                                                                          *
  426. *   DESCRIPTION:                                                           *
  427. *                                                                          *
  428. *       This function tests the XMSIF call XMMrawcall().                   *
  429. *                                                                          *
  430. *   ENTRY:                                                                 *
  431. *                                                                          *
  432. *       Void.                                                              *
  433. *                                                                          *
  434. *   EXIT:                                                                  *
  435. *                                                                          *
  436. *       Void.                                                              *
  437. *                                                                          *
  438. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  439. *                                                                          *
  440. ***************************************************************************/
  441. void do_rawcall_tests()
  442. {
  443.     unsigned long xmsfree, xmsallfree;
  444.     struct XMMregs r;
  445.     int status;
  446.  
  447.     /* first, get something to check against */
  448.     xmsfree = test_XMMcoreleft();
  449.     xmsallfree = test_XMMallcoreleft();
  450.     printf("XMMcoreleft: %lu bytes (%luK)  XMMallcoreleft: %lu bytes (%luK)\n",
  451.                  xmsfree, (xmsfree / 1024L), xmsallfree, (xmsallfree / 1024L));
  452.  
  453.     TESTHEADER();
  454.     printf("Testing XMMrawcall() against XMMcoreleft()/XMMallcoreleft().\n");
  455.     printf("Should succeed.\n");
  456.     r.regAX = 0x0800;
  457.     status = XMMrawcall(&r);
  458.     TRIPLECHECK("XMMrawcall()", status, 0, (void far *) NULL, 0, 0);
  459.     if ((r.regAX != (xmsfree / 1024L)) || (r.regDX != (xmsallfree / 1024L)))
  460.     {
  461.         printf("XMMrawcall() returned %uK and %uK.\n", r.regAX, r.regDX);
  462.         exit(3);
  463.     }
  464.     TESTTAILER();
  465.  
  466.     return;
  467. } /* end of do_rawcall_tests() */
  468.  
  469.  
  470. /***************************************************************************
  471. *   FUNCTION: DO_NCOPY1_TESTS                                              *
  472. *                                                                          *
  473. *   DESCRIPTION:                                                           *
  474. *                                                                          *
  475. *       Tests normal copy functions (_XMMcopy() and macros).               *
  476. *                                                                          *
  477. *   ENTRY:                                                                 *
  478. *                                                                          *
  479. *       None.                                                              *
  480. *                                                                          *
  481. *   EXIT:                                                                  *
  482. *                                                                          *
  483. *       Void.                                                              *
  484. *                                                                          *
  485. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  486. *                                                                          *
  487. ***************************************************************************/
  488. void do_ncopy1_tests(void)
  489. {
  490.     int handle = 0;  /* dummy, to make some macros happy */
  491.     unsigned char far *realbuf;
  492.     unsigned char far *guard1, far *guard2, far *guard3;
  493.     unsigned char far *testbuf;
  494.     unsigned char far *testbuf2;
  495.     int status;
  496.  
  497.     /* allocate a conventional memory buffer */
  498.     realbuf = (unsigned char far *) LMALLOC((MINFREE/1024L) + 3);
  499.     if (realbuf == (unsigned char far *) NULL)
  500.     {
  501.         printf("Can't allocate conventional buffer. Aborting.\n");
  502.         exit(3);
  503.     }
  504.  
  505.     /*
  506.     ** Since we can't access EMBs directly, the only way we have of getting
  507.     ** data there is via the copy functions, which we're trying to test. So
  508.     ** the first round of tests will copy data from one half of the
  509.     ** conventional memory to the other, something which we can verify
  510.     ** directly.
  511.     **
  512.     ** Since _XMMcopy is symmetrical, we only need to give one direction
  513.     ** a real workout.
  514.     */
  515.     guard1 = realbuf;
  516.     FMEMSET(guard1, GUARDVAL, 1024);
  517.     testbuf = (unsigned char far *) normptr(guard1 + 1024);
  518.     guard2 = (unsigned char far *) normptr(testbuf + HALFLEN);
  519.     FMEMSET(guard2, GUARDVAL, 1024);
  520.     testbuf2 = (unsigned char far *) normptr(guard2 + 1024);
  521.     guard3 = (unsigned char far *) normptr(testbuf2 + HALFLEN);
  522.     FMEMSET(guard3, GUARDVAL, 1024);
  523.     gblmsg = "  COPY TESTS CONVENTIONAL-CONVENTIONAL";
  524.  
  525.     /* fill first buffer with incrementing words */
  526.     farincwordfill(testbuf, HALFLEN, 0);
  527.     /* fill second buffer with zero */
  528.     FMEMSET(testbuf2, 0, HALFLEN);
  529.  
  530.     /* try an even-length copy from offset 0 to offset 0 */
  531.     TESTHEADER();
  532.     printf("_XMMcopy(): even-length copy from offset 0 to offset 0.\n");
  533.     printf("Should succeed.\n");
  534.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  535.                                                      (unsigned long) testbuf2);
  536.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  537.     GUARDCHECK(0);
  538.     SRCWORDCHECK(testbuf, HALFLEN);
  539.     CPYWORDCHECK(testbuf2, 50);
  540.     ZEROCHECK((testbuf2 + 50), (HALFLEN - 50));
  541.     TESTTAILER();
  542.  
  543.     /* restore destination pattern */
  544.     FMEMSET(testbuf2, 0, HALFLEN);
  545.  
  546.     /* try an even-length copy from offset 0 to arbitrary offset */
  547.     TESTHEADER();
  548.     printf("_XMMcopy(): even-length copy from offset 0 to arbitrary offset.\n");
  549.     printf("Should succeed.\n");
  550.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  551.                                               (unsigned long)(testbuf2 + 477));
  552.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  553.     GUARDCHECK(0);
  554.     SRCWORDCHECK(testbuf, HALFLEN);
  555.     ZEROCHECK(testbuf2, 477);
  556.     MEMCMP(testbuf, (testbuf2 + 477), 50);
  557.     ZEROCHECK((testbuf2 + 477 + 50), ((HALFLEN - 477) - 50));
  558.     TESTTAILER();
  559.  
  560.     /* restore destination pattern */
  561.     FMEMSET(testbuf2, 0, HALFLEN);
  562.  
  563.     /* try an even-length copy from offset 0 to just before the end */
  564.     TESTHEADER();
  565.     printf("_XMMcopy(): even-length copy from offset 0 to just before end.\n");
  566.     printf("Should succeed.\n");
  567.     status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
  568.                                      (unsigned long)(testbuf2 + HALFLEN - 50));
  569.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  570.     GUARDCHECK(0);
  571.     SRCWORDCHECK(testbuf, HALFLEN);
  572.     ZEROCHECK(testbuf2, (HALFLEN - 50));
  573.     CPYWORDCHECK((testbuf2 + HALFLEN - 50), 50);
  574.     TESTTAILER();
  575.  
  576.     /* restore destination pattern */
  577.     FMEMSET(testbuf2, 0, HALFLEN);
  578.  
  579.     /* try an even-length copy from arbitrary offset to arbitrary offset */
  580.     TESTHEADER();
  581.     printf("_XMMcopy(): even-length copy from arbitrary offset to ");
  582.     printf("arbitrary offset.\nShould succeed.");
  583.     status = _XMMcopy(50, 0, (unsigned long)(testbuf + 384), 0,
  584.                                            (unsigned long)(testbuf2 + 33333U));
  585.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  586.     GUARDCHECK(0);
  587.     SRCWORDCHECK(testbuf, HALFLEN);
  588.     ZEROCHECK(testbuf2, 33333U);
  589.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 50);
  590.     ZEROCHECK((testbuf2 + 33333U + 50), ((HALFLEN - 33333U) - 50));
  591.     TESTTAILER();
  592.  
  593.     /* restore destination pattern */
  594.     FMEMSET(testbuf2, 0, HALFLEN);
  595.  
  596.     /* try an even-length copy from just before the end to arbitrary offset */
  597.     TESTHEADER();
  598.     printf("_XMMcopy(): even-length copy from just before end to arbitrary.\n");
  599.     printf("Should succeed.\n");
  600.     status = _XMMcopy(50, 0, (unsigned long)(testbuf + HALFLEN - 50), 0,
  601.                                              (unsigned long)(testbuf2 + 7676));
  602.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  603.     GUARDCHECK(0);
  604.     SRCWORDCHECK(testbuf, HALFLEN);
  605.     ZEROCHECK(testbuf2, 7676);
  606.     MEMCMP((testbuf + HALFLEN - 50), (testbuf2 + 7676), 50);
  607.     ZEROCHECK((testbuf2 + 7676 + 50), ((HALFLEN - 7676) - 50));
  608.     TESTTAILER();
  609.  
  610.     /* restore destination pattern */
  611.     FMEMSET(testbuf2, 0, HALFLEN);
  612.  
  613.  
  614.     /* try an odd-length copy from offset 0 to offset 0 */
  615.     TESTHEADER();
  616.     printf("_XMMcopy(): odd-length copy from offset 0 to offset 0.\n");
  617.     printf("Should succeed.\n");
  618.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  619.                                                      (unsigned long) testbuf2);
  620.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  621.     GUARDCHECK(0);
  622.     SRCWORDCHECK(testbuf, HALFLEN);
  623.     MEMCMP(testbuf, testbuf2, 111);
  624.     ZEROCHECK((testbuf2 + 111), (HALFLEN - 111));
  625.     TESTTAILER();
  626.  
  627.     /* restore destination pattern */
  628.     FMEMSET(testbuf2, 0, HALFLEN);
  629.  
  630.     /* try an odd-length copy from offset 0 to offset misc */
  631.     TESTHEADER();
  632.     printf("_XMMcopy(): odd-length copy from offset 0 to arbitrary offset.\n");
  633.     printf("Should succeed.\n");
  634.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  635.                                               (unsigned long)(testbuf2 + 477));
  636.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  637.     GUARDCHECK(0);
  638.     SRCWORDCHECK(testbuf, HALFLEN);
  639.     ZEROCHECK(testbuf2, 477);
  640.     MEMCMP(testbuf, (testbuf2 + 477), 111);
  641.     ZEROCHECK((testbuf2 + 477 + 111), ((HALFLEN - 477) - 111));
  642.     TESTTAILER();
  643.  
  644.     /* restore destination pattern */
  645.     FMEMSET(testbuf2, 0, HALFLEN);
  646.  
  647.     /* try an odd-length copy from offset 0 to just before the end */
  648.     TESTHEADER();
  649.     printf("_XMMcopy(): odd-length copy from offset 0 to just before end.\n");
  650.     printf("Should succeed.\n");
  651.     status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
  652.                                     (unsigned long)(testbuf2 + HALFLEN - 111));
  653.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  654.     GUARDCHECK(0);
  655.     SRCWORDCHECK(testbuf, HALFLEN);
  656.     ZEROCHECK(testbuf2, (HALFLEN - 111));
  657.     MEMCMP(testbuf, (testbuf2 + HALFLEN - 111), 111);
  658.     TESTTAILER();
  659.  
  660.     /* restore destination pattern */
  661.     FMEMSET(testbuf2, 0, HALFLEN);
  662.  
  663.     /* try an odd-length copy from arbitrary offset to arbitrary offset */
  664.     TESTHEADER();
  665.     printf("_XMMcopy(): odd-length copy from arbitrary offset to ");
  666.     printf("arbitrary offset.\nShould succeed.\n");
  667.     status = _XMMcopy(111, 0, (unsigned long)(testbuf + 384), 0,
  668.                                            (unsigned long)(testbuf2 + 33333U));
  669.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  670.     GUARDCHECK(0);
  671.     SRCWORDCHECK(testbuf, HALFLEN);
  672.     ZEROCHECK(testbuf2, 33333U);
  673.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 111);
  674.     ZEROCHECK((testbuf2 + 33333U + 111), ((HALFLEN - 33333U) - 111));
  675.     TESTTAILER();
  676.  
  677.     /* restore destination pattern */
  678.     FMEMSET(testbuf2, 0, HALFLEN);
  679.  
  680.     /* try an odd-length copy from just before the end to arbitrary offset */
  681.     TESTHEADER();
  682.     printf("_XMMcopy(): odd-length copy from just before end to arbitrary.\n");
  683.     printf("Should succeed.\n");
  684.     status = _XMMcopy(111, 0, (unsigned long)(testbuf + HALFLEN - 111), 0,
  685.                                              (unsigned long)(testbuf2 + 7676));
  686.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  687.     GUARDCHECK(0);
  688.     SRCWORDCHECK(testbuf, HALFLEN);
  689.     ZEROCHECK(testbuf2, 7676);
  690.     MEMCMP((testbuf + HALFLEN - 111), (testbuf2 + 7676), 111);
  691.     ZEROCHECK((testbuf2 + 7676 + 111), ((HALFLEN - 7676) - 111));
  692.     TESTTAILER();
  693.  
  694.     /* restore destination pattern */
  695.     FMEMSET(testbuf2, 0, HALFLEN);
  696.  
  697.  
  698.     /* try a one-byte copy from offset 0 to offset 0 */
  699.     TESTHEADER();
  700.     printf("_XMMcopy(): one-byte copy from offset 0 to offset 0.\n");
  701.     printf("Should succeed.\n");
  702.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  703.                                                      (unsigned long) testbuf2);
  704.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  705.     GUARDCHECK(0);
  706.     SRCWORDCHECK(testbuf, HALFLEN);
  707.     MEMCMP(testbuf, testbuf2, 1);
  708.     ZEROCHECK((testbuf2 + 1), (HALFLEN - 1));
  709.     TESTTAILER();
  710.  
  711.     /* restore destination pattern */
  712.     FMEMSET(testbuf2, 0, HALFLEN);
  713.  
  714.     /* try a one-byte copy from offset 0 to offset misc */
  715.     TESTHEADER();
  716.     printf("_XMMcopy(): one-byte copy from offset 0 to arbitrary offset.\n");
  717.     printf("Should succeed.\n");
  718.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  719.                                               (unsigned long)(testbuf2 + 477));
  720.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  721.     GUARDCHECK(0);
  722.     SRCWORDCHECK(testbuf, HALFLEN);
  723.     ZEROCHECK(testbuf2, 477);
  724.     MEMCMP(testbuf, (testbuf2 + 477), 1);
  725.     ZEROCHECK((testbuf2 + 477 + 1), ((HALFLEN - 477) - 1));
  726.     TESTTAILER();
  727.  
  728.     /* restore destination pattern */
  729.     FMEMSET(testbuf2, 0, HALFLEN);
  730.  
  731.     /* try a one-byte copy from offset 0 to just before the end */
  732.     TESTHEADER();
  733.     printf("_XMMcopy(): one-byte copy from offset 0 to just before end.\n");
  734.     printf("Should succeed.\n");
  735.     status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
  736.                                       (unsigned long)(testbuf2 + HALFLEN - 1));
  737.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  738.     GUARDCHECK(0);
  739.     SRCWORDCHECK(testbuf, HALFLEN);
  740.     ZEROCHECK(testbuf2, (HALFLEN - 1));
  741.     MEMCMP(testbuf, (testbuf2 + HALFLEN - 1), 1);
  742.     TESTTAILER();
  743.  
  744.     /* restore destination pattern */
  745.     FMEMSET(testbuf2, 0, HALFLEN);
  746.  
  747.     /* try a one-byte copy from arbitrary offset to arbitrary offset */
  748.     TESTHEADER();
  749.     printf("_XMMcopy(): one-byte copy from arbitrary offset to ");
  750.     printf("arbitrary offset.\nShould succeed.");
  751.     status = _XMMcopy(1, 0, (unsigned long)(testbuf + 384), 0,
  752.                                            (unsigned long)(testbuf2 + 33333U));
  753.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  754.     GUARDCHECK(0);
  755.     SRCWORDCHECK(testbuf, HALFLEN);
  756.     ZEROCHECK(testbuf2, 33333U);
  757.     MEMCMP((testbuf + 384), (testbuf2 + 33333U), 1);
  758.     ZEROCHECK((testbuf2 + 33333U + 1), ((HALFLEN - 33333U) - 1));
  759.     TESTTAILER();
  760.  
  761.     /* restore destination pattern */
  762.     FMEMSET(testbuf2, 0, HALFLEN);
  763.  
  764.     /* try a one-byte copy from just before the end to arbitrary offset */
  765.     TESTHEADER();
  766.     printf("_XMMcopy(): one-byte copy from just before end to arbitrary.\n");
  767.     printf("Should succeed.\n");
  768.     status = _XMMcopy(1, 0, (unsigned long)(testbuf + HALFLEN - 1), 0,
  769.                                              (unsigned long)(testbuf2 + 7676));
  770.     TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
  771.     GUARDCHECK(0);
  772.     SRCWORDCHECK(testbuf, HALFLEN);
  773.     ZEROCHECK(testbuf2, 7676);
  774.     MEMCMP((testbuf + HALFLEN - 1), (testbuf2 + 7676), 1);
  775.     ZEROCHECK((testbuf2 + 7676 + 1), ((HALFLEN - 7676) - 1));
  776.     TESTTAILER();
  777.  
  778.     /*
  779.     ** Clean up.
  780.     */
  781.     LFREE(realbuf);
  782.  
  783.     return;
  784. } /* end of do_ncopy1_tests() */
  785.  
  786.  
  787. /*
  788. ** The following group of functions {test_XMM*()} are wrapper functions
  789. ** that call the XMSIF function named and perform preliminary checks on
  790. ** the return values. This keeps code size down since the check only has
  791. ** to be coded in one place.
  792. */
  793.  
  794.  
  795. /***************************************************************************
  796. *   FUNCTION: TEST_XMMCORELEFT                                             *
  797. *                                                                          *
  798. *   DESCRIPTION:                                                           *
  799. *                                                                          *
  800. *       This function calls XMSIF function XMMcoreleft() and checks the    *
  801. *       return value to see if it is a multiple of 1024 (the minimum XMS   *
  802. *       allocation unit).                                                  *
  803. *                                                                          *
  804. *   ENTRY:                                                                 *
  805. *                                                                          *
  806. *       Void.                                                              *
  807. *                                                                          *
  808. *   EXIT:                                                                  *
  809. *                                                                          *
  810. *       Returns the value returned by XMMcoreleft().                       *
  811. *                                                                          *
  812. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  813. *                                                                          *
  814. ***************************************************************************/
  815. unsigned long test_XMMcoreleft(void)
  816. {
  817.     unsigned long xmsfree;
  818.  
  819.     /* call XMMcoreleft and check error code */
  820.     xmsfree = XMMcoreleft();
  821.     weirdcodechk("XMMcoreleft()", 0, (void far *) NULL, 0, 0);
  822.  
  823.     /* check if free byte count is multiple of 1024 */
  824.     if ((xmsfree % 1024L) != 0)
  825.     {
  826.         printf("XMMcoreleft() returned strange number %lu.\n", xmsfree);
  827.         exit(3);
  828.     }
  829.  
  830.     return xmsfree;
  831. } /* end of test_XMMcoreleft() */
  832.  
  833.  
  834. /***************************************************************************
  835. *   FUNCTION: TEST_XMMALLCORELEFT                                          *
  836. *                                                                          *
  837. *   DESCRIPTION:                                                           *
  838. *                                                                          *
  839. *       This function calls XMSIF function XMMallcoreleft() and checks     *
  840. *       the return value to see if it is a multiple of 1024 (the minimum   *
  841. *       XMS allocation unit).                                              *
  842. *                                                                          *
  843. *   ENTRY:                                                                 *
  844. *                                                                          *
  845. *       Void.                                                              *
  846. *                                                                          *
  847. *   EXIT:                                                                  *
  848. *                                                                          *
  849. *       Returns the value returned by XMMallcoreleft().                    *
  850. *                                                                          *
  851. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  852. *                                                                          *
  853. ***************************************************************************/
  854. unsigned long test_XMMallcoreleft(void)
  855. {
  856.     unsigned long xmsfree;
  857.  
  858.     /* call XMMallcoreleft and check error code */
  859.     xmsfree = XMMallcoreleft();
  860.     weirdcodechk("XMMallcoreleft()", 0, (void far *) NULL, 0, 0);
  861.  
  862.     /* check if free byte count is multiple of 1024 */
  863.     if ((xmsfree % 1024L) != 0)
  864.     {
  865.         printf("XMMallcoreleft() returned strange number %lu.\n", xmsfree);
  866.         exit(3);
  867.     }
  868.  
  869.     return xmsfree;
  870. } /* end of test_XMMallcoreleft() */
  871.  
  872.  
  873. /***************************************************************************
  874. *   FUNCTION: TEST_XMMALLOC                                                *
  875. *                                                                          *
  876. *   DESCRIPTION:                                                           *
  877. *                                                                          *
  878. *       This function calls XMSIF function XMMalloc() and checks the       *
  879. *       return codes.                                                      *
  880. *                                                                          *
  881. *   ENTRY:                                                                 *
  882. *                                                                          *
  883. *       bytes - bytes of XMS to allocate                                   *
  884. *                                                                          *
  885. *   EXIT:                                                                  *
  886. *                                                                          *
  887. *       Returns the handle returned by XMMalloc().                         *
  888. *                                                                          *
  889. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  890. *                                                                          *
  891. ***************************************************************************/
  892. int test_XMMalloc(unsigned long bytes)
  893. {
  894.     int handle;
  895.  
  896.     /* call XMMalloc() and check the return */
  897.     handle = XMMalloc(bytes);
  898.     weirdcodechk("XMMalloc()", 0, (void far *) NULL, 0, 0);
  899.  
  900.     return handle;
  901. } /* end of test_XMMalloc() */
  902.  
  903.  
  904. /***************************************************************************
  905. *   FUNCTION: TEST_XMMFREE                                                 *
  906. *                                                                          *
  907. *   DESCRIPTION:                                                           *
  908. *                                                                          *
  909. *       This function calls XMSIF function XMMfree() and checks the        *
  910. *       return codes.                                                      *
  911. *                                                                          *
  912. *   ENTRY:                                                                 *
  913. *                                                                          *
  914. *       handle - XMS EMB handle to be freed                                *
  915. *                                                                          *
  916. *   EXIT:                                                                  *
  917. *                                                                          *
  918. *       Void.                                                              *
  919. *                                                                          *
  920. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  921. *                                                                          *
  922. ***************************************************************************/
  923. void test_XMMfree(int handle)
  924. {
  925.     int status;
  926.  
  927.     /* call XMMfree() and check the return */
  928.     status = XMMfree(handle);
  929.     TRIPLECHECK("XMMfree()", status, 0, (void far *) NULL, 0, 0);
  930.  
  931.     return;
  932. } /* end of test_XMMfree() */
  933.  
  934.  
  935. /*
  936. ** The following group of functions are used to speed up return checking
  937. ** and keep code size down, since the return check only has to be coded
  938. ** in one place. They are used in various macros to further compact and
  939. ** clarify the code.
  940. */
  941.  
  942. /***************************************************************************
  943. *   FUNCTION: WEIRDRETCHK                                                  *
  944. *                                                                          *
  945. *   DESCRIPTION:                                                           *
  946. *                                                                          *
  947. *       This function checks to see if the status value passed to it is    *
  948. *       either 0 or XMMOOPS, and assumes something has gone wrong if it    *
  949. *       is not. If something has gone wrong, does some clean up before     *
  950. *       exiting.                                                           *
  951. *                                                                          *
  952. *   ENTRY:                                                                 *
  953. *                                                                          *
  954. *       function - name of function which may have goofed                  *
  955. *       status   - status value to check                                   *
  956. *       tofree1  - conventional memory block to be freed on exit. Not      *
  957. *                  freed if NULL.                                          *
  958. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  959. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  960. *                                                                          *
  961. *   EXIT:                                                                  *
  962. *                                                                          *
  963. *       Void, or may not return.                                           *
  964. *                                                                          *
  965. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  966. *                                                                          *
  967. ***************************************************************************/
  968. void weirdretchk(char *function, int status, void far *tofree1, int tofree2,
  969.                                                                    int tofree3)
  970. {
  971.     if ((status != XMMOOPS) && (status != 0))
  972.     {
  973.         printf("%s returned weird value %d, code 0x%X.\n", function, status,
  974.                                                      (unsigned int) _XMMerror);
  975.         if (tofree1 != (void far *) NULL)
  976.         {
  977.             LFREE(tofree1);
  978.         }
  979.         if (tofree2 != 0)
  980.         {
  981.             XMMfree(tofree2);
  982.         }
  983.         if (tofree3 != 0)
  984.         {
  985.             XMMfree(tofree3);
  986.         }
  987.         exit(3);
  988.     }
  989.  
  990.     return;
  991. } /* end of weirdretchk() */
  992.  
  993.  
  994. /***************************************************************************
  995. *   FUNCTION: WEIRDCODECHK                                                 *
  996. *                                                                          *
  997. *   DESCRIPTION:                                                           *
  998. *                                                                          *
  999. *       This function checks to see if the XMSIF error code value matches *
  1000. *       the expected value, and assumes something has gone wrong if it     *
  1001. *       does not. If something has gone wrong, does some clean up before   *
  1002. *       exiting.                                                           *
  1003. *                                                                          *
  1004. *   ENTRY:                                                                 *
  1005. *                                                                          *
  1006. *       function - name of function which may have goofed                  *
  1007. *       expected - expected value of _XMMerror                             *
  1008. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1009. *                  freed if NULL.                                          *
  1010. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1011. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1012. *                                                                          *
  1013. *   EXIT:                                                                  *
  1014. *                                                                          *
  1015. *       Void, or may not return.                                           *
  1016. *                                                                          *
  1017. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1018. *                                                                          *
  1019. ***************************************************************************/
  1020. void weirdcodechk(char *function, int expected, void far *tofree1, int tofree2,
  1021.                                                                    int tofree3)
  1022. {
  1023.     if ((int) _XMMerror != expected)
  1024.     {
  1025.         printf("%s returned unexpected code 0x%X.\n", function,
  1026.                                                      (unsigned int) _XMMerror);
  1027.         if (tofree1 != (void far *) NULL)
  1028.         {
  1029.             LFREE(tofree1);
  1030.         }
  1031.         if (tofree2 != 0)
  1032.         {
  1033.             XMMfree(tofree2);
  1034.         }
  1035.         if (tofree3 != 0)
  1036.         {
  1037.             XMMfree(tofree3);
  1038.         }
  1039.         exit(3);
  1040.     }
  1041.  
  1042.     return;
  1043. } /* end of weirdcodechk() */
  1044.  
  1045.  
  1046. /***************************************************************************
  1047. *   FUNCTION: FAILCHECK                                                    *
  1048. *                                                                          *
  1049. *   DESCRIPTION:                                                           *
  1050. *                                                                          *
  1051. *       This function checks to see if the status value passed to it is    *
  1052. *       XMMOOPS and exits if it is. failcheck() is used when a function    *
  1053. *       is expected to succeed. Does some clean up before exiting.         *
  1054. *                                                                          *
  1055. *   ENTRY:                                                                 *
  1056. *                                                                          *
  1057. *       function - name of function which may have goofed                  *
  1058. *       status   - status value to be checked                              *
  1059. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1060. *                  freed if NULL.                                          *
  1061. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1062. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1063. *                                                                          *
  1064. *   EXIT:                                                                  *
  1065. *                                                                          *
  1066. *       Void, or may not return.                                           *
  1067. *                                                                          *
  1068. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1069. *                                                                          *
  1070. ***************************************************************************/
  1071. void failcheck(char *function, int status, void far *tofree1, int tofree2,
  1072.                                                                   int tofree3)
  1073. {
  1074.     if (status == XMMOOPS)
  1075.     {
  1076.         printf("%s failed, code 0x%X.\n", function, (unsigned int) _XMMerror);
  1077.         if (tofree1 != (void far *) NULL)
  1078.         {
  1079.             LFREE(tofree1);
  1080.         }
  1081.         if (tofree2 != 0)
  1082.         {
  1083.             XMMfree(tofree2);
  1084.         }
  1085.         if (tofree3 != 0)
  1086.         {
  1087.             XMMfree(tofree3);
  1088.         }
  1089.         exit(3);
  1090.     }
  1091.  
  1092.     return;
  1093. } /* end of failcheck() */
  1094.  
  1095.  
  1096. /***************************************************************************
  1097. *   FUNCTION: NOFAILCHECK                                                  *
  1098. *                                                                          *
  1099. *   DESCRIPTION:                                                           *
  1100. *                                                                          *
  1101. *       This function checks to see if the status value passed to it is    *
  1102. *       0 and exits if it is. nofailcheck() is used when a function is     *
  1103. *       expected to fail. Does some clean up before exiting.               *
  1104. *                                                                          *
  1105. *   ENTRY:                                                                 *
  1106. *                                                                          *
  1107. *       function - name of function which may have goofed                  *
  1108. *       status   - status value to be checked                              *
  1109. *       tofree1  - conventional memory block to be freed on exit. Not      *
  1110. *                  freed if NULL.                                          *
  1111. *       tofree2  - XMS handle to be freed on exit. Not freed if 0.         *
  1112. *       tofree2  - another XMS handle to be freed on exit. Not freed if 0. *
  1113. *                                                                          *
  1114. *   EXIT:                                                                  *
  1115. *                                                                          *
  1116. *       Void, or may not return.                                           *
  1117. *                                                                          *
  1118. *   CONSTRAINTS/SIDE EFFECTS:                                              *
  1119. *                                                                          *
  1120. ***************************************************************************/
  1121. void nofailcheck(char *function, int status, void far *tofree1, int tofree2,
  1122.                                                                   int tofree3)
  1123. {
  1124.     if (status == 0)
  1125.     {
  1126.         printf("%s did not fail.\n", function);
  1127.         if (tofree1 != (void far *) NULL)
  1128.         {
  1129.             LFREE(tofree1);
  1130.         }
  1131.         if (tofree2 != 0)
  1132.         {
  1133.             XMMfree(tofree2);
  1134.         }
  1135.         if (tofree3 != 0)
  1136.         {
  1137.             XMMfree(tofree3);
  1138.         }
  1139.         exit(3);
  1140.     }
  1141.  
  1142.     return;
  1143. } /* end of nofailcheck() */
  1144.  
  1145.